/**
 * Copyright 2017 汉威.智慧环保事业部.
 * Created by 毛超然 on 2017/09/13 15:11.12
 * <p>
 * 溯源service层方法
 */
package com.hw.one.peach.core.service;

import com.alibaba.fastjson.JSONObject;
import com.hw.one.core.result.MsgResult;
import com.hw.one.dam2.util.HttpClientUtil;
import com.hw.one.peach.core.dao.ITraceAnalysisDao;
import com.hw.one.peach.core.po.*;
import com.hw.one.util.DateTimeUtil;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class TraceAnalysisService implements ITraceAnalysisService {

    @Resource
    private ITraceAnalysisDao traceAnalysisDao;

    private final String TRACE_ANALYSIS_URL = "http://10.0.16.11:36000/analysis/tracingAnalysis?format=json";

    /**
     * 查询溯源追踪数据
     *
     * @param paramMap
     * @return
     */

    @Override
    public Map<String, Object> findTraceabilityData(Map<String, Object> paramMap) throws Exception {
        String siteCode = (String) paramMap.get("siteCode");
        String occurTime = (String) paramMap.get("occurTime");
        String dataType = (String) paramMap.get("dataType");

        // 封装参数
        Map<String, Object> paraMap = new HashMap<>();
        paraMap.put("siteCode", siteCode);
        paraMap.put("monitorTime", occurTime);
        // 查询mongo库，获取数据
        List<TraceDataPO> dataList = this.traceAnalysisDao.findTraceabilityDataBySiteCodeAndTime(paraMap);

        if (null == dataList || dataList.size() < 1 || null == dataList.get(0)) {
            return new HashedMap();
        }
        // 得到最近的一条数据
        TraceDataPO traceDataPO = dataList.get(0);
        // 数据处理
        if ("real".equals(dataType)) {
            return putTraceRealData(traceDataPO);
        } else if ("history".equals(dataType)) {
            return putTraceHistoryData(traceDataPO);
        } else {
            return new HashedMap();
        }

    }

    /**
     * 溯源实时数据的封装
     *
     * @param traceDataPO
     * @return
     */

    private Map<String, Object> putTraceRealData(TraceDataPO traceDataPO) {
        Map<String, Object> returnMap = new HashMap<>();

        returnMap.put("standSite", putTraceStandSiteData(traceDataPO.getSTANDSITE()));
        returnMap.put("calculate", putTraceCalculateData(traceDataPO.getCALCULATE()));

        returnMap.put("raiseDust", putTraceSiteData(traceDataPO.getRAISEDUST(), "raiseDust", "real"));
        returnMap.put("smallSite", putTraceSiteData(traceDataPO.getSMALLSITE(), "smallSite", "real"));
        returnMap.put("pollution", putTraceSiteData(traceDataPO.getPOLLUTION(), "pollution", "real"));

        returnMap.put("slagCar", putTraceSlagCarData(traceDataPO.getSLAGCAR()));
        returnMap.put("suggest", traceDataPO.getSUGGEST());
        returnMap.put("type", traceDataPO.getTYPE());
        return returnMap;
    }


    /**
     * 溯源历史数据的封装
     *
     * @param traceDataPO
     * @return
     */
    private Map<String, Object> putTraceHistoryData(TraceDataPO traceDataPO) {
        Map<String, Object> returnMap = new HashMap<>();
        returnMap.put("standSite", putTraceStandSiteData(traceDataPO.getSTANDSITE()));
        returnMap.put("calculate", putTraceCalculateData(traceDataPO.getCALCULATE()));
        returnMap.put("condition", putTraceConditionData(traceDataPO.getCONDITION()));

        returnMap.put("raiseDust", putTraceSiteData(traceDataPO.getRAISEDUST(), "raiseDust", "history"));
        returnMap.put("smallSite", putTraceSiteData(traceDataPO.getSMALLSITE(), "smallSite", "history"));
        returnMap.put("pollution", putTraceSiteData(traceDataPO.getPOLLUTION(), "pollution", "history"));

        returnMap.put("suggest", traceDataPO.getSUGGEST());
        returnMap.put("type", traceDataPO.getTYPE());

        return returnMap;
    }

    /**
     * 标准站数据的封装
     *
     * @param standDataPO
     * @return
     */

    private Map<String, Object> putTraceStandSiteData(TraceStandDataPO standDataPO) {
        Map<String, Object> standDataMap = new HashedMap();
        if (null != standDataPO) {
            Map<String, Object> monitorDataPO = standDataPO.getMONITORDATA();
            Map<String, Object> foctorMap = new HashedMap();
            if (null != monitorDataPO) {
                foctorMap.put("pm10", monitorDataPO.get("PM10"));
                foctorMap.put("pm25", monitorDataPO.get("PM2_5"));
                foctorMap.put("so2", monitorDataPO.get("SO2"));
                foctorMap.put("no2", monitorDataPO.get("NO2"));
                foctorMap.put("o3", monitorDataPO.get("O3"));
                foctorMap.put("co", monitorDataPO.get("CO"));
                foctorMap.put("hum", monitorDataPO.get("HUM"));
                foctorMap.put("temp", monitorDataPO.get("TEMP"));
                foctorMap.put("aqi", monitorDataPO.get("AQI"));
                foctorMap.put("aqiLevel", monitorDataPO.get("AQILEVEL"));
                foctorMap.put("subIndex", monitorDataPO.get("SUBINDEX"));
            }
            standDataMap.put("monitorData", foctorMap);
            standDataMap.put("siteCode", standDataPO.getSITECODE());
            standDataMap.put("siteName", standDataPO.getSITENAME());
            standDataMap.put("loc", standDataPO.getLOC());
            standDataMap.put("siteTypeCode", standDataPO.getSITETYPECODE());
            standDataMap.put("monitorTime", standDataPO.getMONITORTIME());
        }
        return standDataMap;
    }

    /**
     * 计算结果的封装
     *
     * @param calculateMap
     * @return
     */

    private Map<String, Object> putTraceCalculateData(Map<String, Object> calculateMap) {
        Map<String, Object> calculateDataMap = new HashedMap();
        if (null != calculateMap) {
            calculateDataMap.put("wd", calculateMap.get("WD"));
            calculateDataMap.put("ws", calculateMap.get("WS"));
            calculateDataMap.put("distance", calculateMap.get("DISTANCE"));
            calculateDataMap.put("wdNum", calculateMap.get("WDNUM"));
            calculateDataMap.put("width", calculateMap.get("WIDTH"));
            calculateDataMap.put("place", calculateMap.get("PLACE"));
        }
        return calculateDataMap;
    }

    /**
     * 过程条件的封装
     *
     * @param calculateMap
     * @return
     */

    private Map<String, Object> putTraceConditionData(Map<String, Object> calculateMap) {
        Map<String, Object> conditionDataMap = new HashedMap();
        if (null != calculateMap) {
            conditionDataMap.put("count", calculateMap.get("COUNT"));
            conditionDataMap.put("scope", calculateMap.get("SCOPE"));
            conditionDataMap.put("endTime", calculateMap.get("ENDTIME"));
            conditionDataMap.put("startTime", calculateMap.get("STARTTIME"));
            conditionDataMap.put("timeSlot", calculateMap.get("TIMESLOT"));
        }
        return conditionDataMap;
    }

    /**
     * 溯源渣土车数据的封装
     *
     * @param traceSlagCarDataList
     * @return
     */

    private List<Map<String, Object>> putTraceSlagCarData(List<TraceSlagCarPO> traceSlagCarDataList) {
        List<Map<String, Object>> returnList = new ArrayList<>();
        if (null != traceSlagCarDataList) {
            Map<String, Object> dataMap = new HashMap<>();
            for (TraceSlagCarPO slagCarPO : traceSlagCarDataList) {
                if (null != slagCarPO) {
                    Map<String, Object> historyDataPO = slagCarPO.getHISTORYDATA();
                    Map<String, Object> foctorMap = new HashedMap();
                    if (null != historyDataPO) {
//                        foctorMap.put("time", historyDataPO.get("TIME"));
                        foctorMap.put("data", historyDataPO.get("DATA"));
                    }
                    dataMap.put("historyData", foctorMap);
                    dataMap.put("historyData", slagCarPO.getHISTORYDATA());
                    dataMap.put("companyName", slagCarPO.getCOMPANYNAME());
                    dataMap.put("carCode", slagCarPO.getCARCODE());
                    dataMap.put("loc", slagCarPO.getLOC());
                    dataMap.put("monitorTime", slagCarPO.getMONITORTIME());
                    dataMap.put("deviceCode", slagCarPO.getDEVICECODE());
                    returnList.add(dataMap);
                }
            }
        }

        return returnList;
    }


    /**
     * 溯源站点公共数据的封装操作
     *
     * @param traceSiteDataList
     * @param type              0：实时；1：历史
     * @return
     */

    private List<Map<String, Object>> putTraceSiteData(List<TraceSiteDataPO> traceSiteDataList, String siteType, String type) {
        List<Map<String, Object>> returnList = new ArrayList<>();
        if (null != traceSiteDataList) {
            Map<String, Object> dataMap = null;
            for (TraceSiteDataPO traceSiteDataPO : traceSiteDataList) {
                dataMap = new HashMap<>();
                if (null != traceSiteDataPO) {
                    if ("history".equals(type)) {
                        TraceHistoryDataPO historyDataPO = traceSiteDataPO.getHISTORYDATA();
                        Map<String, Object> foctorMap = new HashedMap();
                        if (null != historyDataPO) {
                            foctorMap.put("time", historyDataPO.getTIME());
                            foctorMap.put("data", historyDataPO.getDATA());
                            foctorMap.put("name", historyDataPO.getNAME());
                        }
                        dataMap.put("historyData", foctorMap);
                    }
                    dataMap.put("siteCode", traceSiteDataPO.getSITECODE());
                    dataMap.put("siteName", traceSiteDataPO.getSITENAME());
                    dataMap.put("loc", traceSiteDataPO.getLOC());
                    dataMap.put("siteTypeCode", traceSiteDataPO.getSITETYPECODE());
                    Map<String, Object> monitorData = traceSiteDataPO.getMONITORDATA();
                    if (null != monitorData) {
                        Map<String, Object> foctorMap = new HashedMap();
                        if ("raiseDust".equals(siteType)) {
                            foctorMap.put("pm10", monitorData.get("PM10"));
                            foctorMap.put("wd", monitorData.get("WD"));
                            foctorMap.put("ws", monitorData.get("WS"));
                            foctorMap.put("noise", monitorData.get("NOISE"));
                            foctorMap.put("pm25", monitorData.get("PM2_5"));
                            foctorMap.put("temp", monitorData.get("TEMP"));
                            foctorMap.put("hum", monitorData.get("HUM"));
                        } else if ("smallSite".equals(siteType)) {
                            foctorMap.put("pm10", monitorData.get("PM10"));
                            foctorMap.put("pm25", monitorData.get("PM2_5"));
                            foctorMap.put("so2", monitorData.get("SO2"));
                            foctorMap.put("no2", monitorData.get("NO2"));
                            foctorMap.put("o3", monitorData.get("O3"));
                            foctorMap.put("co", monitorData.get("CO"));
                            foctorMap.put("pollutant", monitorData.get("POLLUTANT"));
                            foctorMap.put("aqi", monitorData.get("AQI"));
                            foctorMap.put("aqiLevel", monitorData.get("AQILEVEL"));
                            foctorMap.put("aqiLevelType", monitorData.get("AQILEVELTYPE"));
                            foctorMap.put("subIndex", monitorData.get("SUBINDEX"));
                        } else if ("pollution".equals(siteType)) {
                        } else {
                        }
                        dataMap.put("monitorData", foctorMap);
                    }
                    returnList.add(dataMap);
                }
            }
        }

        return returnList;
    }

    /**
     * 实时生成并查询溯源追踪数据
     *
     * @param paramMap
     * @return
     * @throws Exception
     */

    @Override
    public MsgResult findRealTraceabilityDatas(Map<String, Object> paramMap) throws Exception {
        String siteCode = (String) paramMap.get("siteCode");
        String occurTime = (String) paramMap.get("occurTime");
        paramMap.put("dataType", "history");
        // 封装参数
        Map<String, String> paraMap = new HashMap<>();
        paraMap.put("standCode", siteCode);
        paraMap.put("monitorTime", occurTime);
        paraMap.put("format", "json");
        paraMap.put("type", "1");

        MsgResult msgResult = this.tracingAnalysis(paraMap, 0, 3);
        if ("1111".equals(msgResult.getCode())) {
            return MsgResult.okResult(this.findTraceabilityData(paramMap));
        }

        return msgResult;
    }

    /**
     * 调取web接口溯源分析
     *
     * @param paramMap
     * @return 成功返回true;尝试time次调取失败后返回false；
     * @throws Exception
     */

    @Override
    public MsgResult tracingAnalysis(Map<String, String> paramMap, int num, int time) {
        // 尝试次数控制
        if (num > 3) {
            return MsgResult.infoResult("溯源分析超时，请重新尝试");
        }
        Map<String, String> httpResultMap = HttpClientUtil.sendGetWithParams(TRACE_ANALYSIS_URL, new HashMap<>(), paramMap);
        if ("200".equals(httpResultMap.get("statusCode"))) {
            JSONObject resultObj = JSONObject.parseObject(httpResultMap.get("result"));
            System.out.println(httpResultMap.get("result"));
            if ("1111".equals(resultObj.get("code"))) {
                return MsgResult.okResult();
            }else{
                return MsgResult.infoResult("未获取原始数据");
            }
        }
        // 失败后重新调取
        return tracingAnalysis(paramMap, ++num, time);
    }

    /**
     * 根据siteCode和时间查询时间段内的溯源追踪数据
     *
     * @param paramMap
     * @return
     * @throws Exception
     */
    @Override
    public List<Map<String, Object>> findTraceabilityDatas(Map<String, Object> paramMap) throws Exception {
        List<Map<String, Object>> returnList = new ArrayList<>();
        String siteCode = (String) paramMap.get("siteCode");
        String monitorTime = (String) paramMap.get("monitorTime");

        String monitorDateString = DateTimeUtil.getFormatDateStr(monitorTime, "yyyy-MM-dd");

        // 封装参数
        Map<String, Object> paraMap = new HashMap<>();
        paraMap.put("siteCode", siteCode);
        paraMap.put("startTime", monitorDateString + " 00:00:00");
        paraMap.put("endTime", monitorDateString + " 59:59:59");
        // 查询mongo库，获取数据
        List<TraceDataPO> dataList = this.traceAnalysisDao.findTraceabilityDatasBySiteCodeAndTime(paraMap);

        if (null == dataList || dataList.size() < 1) {
            return returnList;
        }
        Map<String, Object> returnMap;
        for (TraceDataPO traceDataPO : dataList) {
            TraceStandDataPO standDataPO = traceDataPO.getSTANDSITE();
            if (null != standDataPO) {
                returnMap = new HashMap<>();
                returnMap.put("siteCode", standDataPO.getSITECODE());
                returnMap.put("monitorTime", standDataPO.getMONITORTIME());
                returnMap.put("type", traceDataPO.getTYPE());
                returnList.add(returnMap);
            }
        }

        return returnList;
    }

}
